<template>
    <div>
        
        <Form :ref="formName" :model="formData" :rules="ruleCustom" :label-width="labelWidth" inline>
            
            <template v-for="(fieldInfo, fieldIndex) in formFieldDefinedInfo">
                
                <FormItem :key="fieldIndex" :label="fieldInfo.label" :prop="fieldIndex">
                    <!--文本-->
                    <Input v-if="fieldInfo.fieldType === fieldTypeList.text" v-model="formData[fieldIndex]" :placeholder="fieldInfo.placeholder"></Input>
                    
                    <!--日期-->
                    <DatePicker
                            v-if="fieldInfo.fieldType === fieldTypeList.datetime"
                            type="datetime"
                            @on-change="dateValue => handleDatePickerOnChange(fieldIndex,dateValue)"
                            :placeholder="fieldInfo.placeholder"
                            v-model="formData[fieldIndex]"
                            :format="fieldInfo.dateFormat"
                    ></DatePicker>
                    
                    <!--日期间隔-->
                    <DatePicker
                            v-if="fieldInfo.fieldType === fieldTypeList.datetimerange"
                            type="datetimerange"
                            @on-change="dateValue => handleDatePickerOnChange(fieldIndex,dateValue)"
                            :placeholder="fieldInfo.placeholder"
                            v-model="formData[fieldIndex]"
                            :format="fieldInfo.dateFormat"
                            style="width: 300px"
                    ></DatePicker>
                    
                    <!--远程获取数据下拉选项-->
                    <Select
                            v-if="fieldInfo.fieldType === fieldTypeList.select && fieldInfo.remote"
                            v-model="formData[fieldIndex]"
                            :multiple="fieldInfo.multiple"
                            :filterable="fieldInfo.filterable"
                            :remote="fieldInfo.remote"
                            :remote-method="query => handlerSelectRemote(query,fieldIndex)"
                            :loading="fieldInfo.loading"
                            :loading-text="fieldInfo.loadingText"
                            :placeholder="fieldInfo.filterable ? '输入搜索' : '请选择'"
                            :clearable="true"
                    >
                        <Option v-for="(optionItem,optionIndex) in fieldInfo.options" :disabled="optionItem.disabled" :key="optionIndex" v-model="optionItem.value">{{optionItem.label}}</Option>
                    </Select>
                    
                    <!--固定数据下拉选项，经实践不可和远程获取选项复用-->
                    <Select
                            v-if="fieldInfo.fieldType === fieldTypeList.select && !fieldInfo.remote"
                            v-model="formData[fieldIndex]"
                            :multiple="fieldInfo.multiple"
                            :clearable="true"
                    >
                        <Option v-for="(optionItem,optionIndex) in fieldInfo.options" :disabled="optionItem.disabled" :key="optionIndex" v-model="optionItem.value">{{optionItem.label}}</Option>
                    </Select>
                    
                    <!--数字范围选择框-->
                    <template v-if="fieldInfo.fieldType === fieldTypeList.number">
                        <InputNumber :step="fieldInfo.step" :precision="fieldInfo.precision" :max="fieldInfo.max" :min="fieldInfo.min" v-model="formData[fieldIndex].min"></InputNumber>
                        --
                        <InputNumber :step="fieldInfo.step" :precision="fieldInfo.precision" :max="fieldInfo.max" :min="fieldInfo.min" v-model="formData[fieldIndex].max"></InputNumber>
                    </template>
                
                </FormItem>
            
            </template>
            
            <FormItem>
                <Button type="primary" @click="handleSubmit">搜索</Button>
                <Button @click="handleReset" style="margin-left: 8px">重置</Button>
            </FormItem>
        </Form>
    </div>
</template>

<script>
    import filterCondition from '../configs/filterConditionOperator'
    import axios from '../../libs/api.request'
    
    export default {
        name   : "TableFilterForm",
        data() {
            return {
                formName            : 'formName',//表单ref
                formData            : {//表单数据，此为动态生成，其下键名为随机生成对应 formFieldDefinedInfo 的键
                
                },
                formDateFieldData   : {//用于记录日期字段的值，由于iview复制不是要的格式
                
                },
                formNumberFieldList : [],//数字字段集合，用于重置时清除数字范围值
                ruleCustom          : {//表单过滤规则
                
                },
                eventList           : {//时间名称定义
                    onSubmitClick: 'on-submit-click',//过滤表单提交触发事件
                },
                formFieldDefinedInfo: {//表单字段定义
                
                },
                fieldTypeList       : {//支持的表单定义类型
                    text         : 'text',
                    select       : 'select',
                    datetime     : 'datetime',
                    datetimerange: 'datetimerange',
                    number       : 'number',
                },
                filterResult     :[],//过滤条件
            };
        },
        props  : {
            formFieldRule: {//表单字段信息
                type: Array,
                default() {
                    return [];
                },
            },
            labelWidth   : {
                type   : Number,
                default: 90,
            },
        },
        methods: {
            handleSubmit() {
                this.$refs[this.formName].validate((valid) => {
                    if (valid) {
                        this.$Message.success('搜索条件设置成功!');
                        this.$emit(this.eventList.onSubmitClick, this.parseCondition());
                    } else {
                        this.$Message.error('Fail!');
                    }
                })
            },
            handleReset() {
                this.formDateFieldData = {};//日期转换记录删除
                
                //清除数字范围字段
                for (let indexField in this.formNumberFieldList) {
                    let randomFieldName                = this.formNumberFieldList[indexField];
                    this.formData[randomFieldName].min = null;
                    this.formData[randomFieldName].max = null;
                }
                
                this.$refs[this.formName].resetFields();
                
                //重置后触发条件修改操作
                this.$Message.success('搜索条件重置成功!');
                this.$emit(this.eventList.onSubmitClick, this.parseCondition());
            },
            parseCondition() {
                let formData     = Object.assign({}, this.formData),
                    filterResult = [];
                
                //组织条件返回
                for (let fieldName in formData) {
                    let fieldDefinedInfo = this.formFieldDefinedInfo[fieldName];
                    
                    //日期格式获取转化值
                    let fieldVal = this.formDateFieldData[fieldName] ? this.formDateFieldData[fieldName] : formData[fieldName];
                    
                    switch (fieldDefinedInfo.fieldType) {
                        case this.fieldTypeList.text:
                            //文本输入框组织like语句
                            fieldVal.length && filterResult.push({
                                field_name: fieldDefinedInfo.fieldName,
                                field_type: fieldDefinedInfo.fieldType,
                                type      : filterCondition.CONTAIN,
                                value     : fieldVal,
                            });
                            break;
                        case this.fieldTypeList.select://select 多选处理
                            //如果是多选，改变type的值 和 组织多选value值
                            let type = filterCondition.EQUAL;
                            if (fieldDefinedInfo.multiple) {
                                //可多选
                                type = filterCondition.IN;
                                
                                if (!fieldVal.length || !fieldVal.join(',')) {//充值或为空后会在数组中留下 [ 0 => '']的数组，这里做下处理
                                    continue;
                                }
                                fieldVal = !fieldDefinedInfo.toInteger ? fieldVal : fieldVal.map(function (val) {
                                     return parseInt(val);
                                });
                            } else {
                                if (fieldVal === undefined || !fieldVal.toString().length) {//单选时值为空则不添加过滤条件
                                    continue;
                                }

                                fieldVal = fieldDefinedInfo.toInteger ? parseInt(fieldVal,10) : fieldVal;
                            }
                            filterResult.push({
                                field_name: fieldDefinedInfo.fieldName,
                                field_type: fieldDefinedInfo.fieldType,
                                type      : type,
                                value     : fieldVal,
                            });
                            
                            break;
                        case this.fieldTypeList.datetime://时间
                            break;
                        case this.fieldTypeList.datetimerange://日期范围组织查询条件组织
                            //拆分成 field >= fooDatetime and field <= barDateTime
                            if (fieldVal.length && fieldVal.join('')) {
                              filterResult.push({
                                    field_name: fieldDefinedInfo.fieldName,
                                    field_type: fieldDefinedInfo.fieldType,
                                    type      : filterCondition.MORE_THAN_AND_EQUAL,
                                    value     : this.dateResultFormatParse(fieldVal[0],fieldDefinedInfo.dateResultFormat),
                                });

                              filterResult.push({
                                    field_name: fieldDefinedInfo.fieldName,
                                    field_type: fieldDefinedInfo.fieldType,
                                    type      : filterCondition.LESS_THAN_AND_EQUAL,
                                    value     : this.dateResultFormatParse(fieldVal[1],fieldDefinedInfo.dateResultFormat),
                                });
                            }
                            
                            break;
                        case this.fieldTypeList.number://数字范围查询条件组织
                            //拆分成 field >= fooNumber and field <= barNumber,
                          fieldVal.min !== null && fieldVal.min && filterResult.push({
                                field_name: fieldDefinedInfo.fieldName,
                                field_type: fieldDefinedInfo.fieldType,
                                type      : filterCondition.MORE_THAN_AND_EQUAL,
                                value     : fieldVal.min,
                            });

                          fieldVal.max !== null && fieldVal.max && filterResult.push({
                                field_name: fieldDefinedInfo.fieldName,
                                field_type: fieldDefinedInfo.fieldType,
                                type      : filterCondition.LESS_THAN_AND_EQUAL,
                                value     : fieldVal.max,
                            });
                            
                            break;
                        default:
                            break;
                    }
                }
    
                this.filterResult = filterResult;
                
                return filterResult;
            },
            dateResultFormatParse(date, dateResultFormat) {//由于数据库存储时间格式不同，日期类型结果转化，以便用于直接搜索
                let result = date;
                switch (dateResultFormat) {
                    case 'intuitive':
                        break;
                    case 's':
                        result = (new Date(date)).getTime() / 1000;
                        break;
                    case 'ms':
                        result = (new Date(date)).getTime();
                        break;
                }
        
                return result;
            },
            handleDatePickerOnChange(fieldIndex, date) {
                this.formDateFieldData[fieldIndex] = date;
            },
            handlerSelectRemote(query, fieldIndex) {
                if (query !== '') {
                    this.formFieldDefinedInfo[fieldIndex].loading = true;
                    
                    //查询关键词字段设置
                    let requestMethod = this.formFieldDefinedInfo[fieldIndex].optionsRemoteUrlMethod.toLocaleLowerCase(),
                        queryDataInfo = {
                            [this.formFieldDefinedInfo[fieldIndex].optionsRemoteQueryParamName]: query
                        };
                    
                    //ajax获取搜索记录
                    let axiosConfig = {
                        method: requestMethod,
                        url   : this.formFieldDefinedInfo[fieldIndex].optionsRemoteUrl,
                        params: requestMethod === 'get' ? Object.assign({}, queryDataInfo, this.formFieldDefinedInfo[fieldIndex].optionsRemoteUrlParams) : this.formFieldDefinedInfo[fieldIndex].optionsRemoteUrlParams,
                        data  : Object.assign({}, queryDataInfo, this.formFieldDefinedInfo[fieldIndex].optionsRemoteUrlData),
                    };
                    axios.request(axiosConfig).then(res => {
                        if (res.data.code !== 0) {
                            this.$Message.error(res.data.msg);
                            
                            throw new Error(res.data.msg);
                        } else {
                            return res.data.data;
                        }
                    }).then(data => {
                        this.formFieldDefinedInfo[fieldIndex].loading = false;
                        
                        //获取列表数据
                        this.formFieldDefinedInfo[fieldIndex].options = data.map(item => {
                            return {
                                value: item[this.formFieldDefinedInfo[fieldIndex].optionsRemoteFieldNameValue],
                                label: item[this.formFieldDefinedInfo[fieldIndex].optionsRemoteFieldNameLabel],
                            };
                        });
                        
                        //如果设置了成功函数则执行
                        this.formFieldDefinedInfo[fieldIndex].optionsRemoteSuccessFn
                        &&
                        this.formFieldDefinedInfo[fieldIndex].optionsRemoteSuccessFn(data);
                        
                    }).catch(err => {
                        this.formFieldDefinedInfo[fieldIndex].loading = false;
                        
                        console.log(err);
                        
                        //如果设置了成功函数则执行
                        this.formFieldDefinedInfo[fieldIndex].optionsRemoteErrorFn
                        &&
                        this.formFieldDefinedInfo[fieldIndex].optionsRemoteErrorFn(err);
                    });
                    
                } else {
                    this.formFieldDefinedInfo[fieldIndex].options = [];
                }
            },
        },
        created() {
            //初始化组织表单
            let randomFormData       = {}, //表单 随机字段 键值信息
                formFieldDefinedInfo = {},//随机表单字段信息
                existGetOnceOption = false; //一次获取下拉框选项
            for (let ruleIndex in this.formFieldRule) {
                let formFieldInfo   = this.formFieldRule[ruleIndex],
                    randomFiledName = formFieldInfo.fieldName + '_randomFieldName_' + Date.now().toString() + '_' + Math.ceil(Math.random() * 1e10).toString();
    
                if(!existGetOnceOption && formFieldInfo.optionRemoteGetOnce) {
                    existGetOnceOption = true;
                }
                
                formFieldDefinedInfo[randomFiledName] = {
                    label      : formFieldInfo.label ? formFieldInfo.label : '未定义名称label',
                    placeholder: formFieldInfo.placeholder ? formFieldInfo.placeholder : '',
                    fieldType  : formFieldInfo.fieldType ? formFieldInfo.fieldType : 'text',//字段类型
                    fieldName  : formFieldInfo.fieldName,//字段名
                    
                    prop: randomFiledName,
                    
                    /**
                     * 各个表单字段类型额外字段
                     */
                    
                    //日期选项
                    dateFormat      : formFieldInfo.dateFormat ? formFieldInfo.dateFormat : 'yyyy-MM-dd HH:mm:ss',//日期格式
                    dateResultFormat: formFieldInfo.dateResultFormat ? formFieldInfo.dateResultFormat : 'intuitive',//选项为 intuitive（字符串直观的形式，e.g, '2019-05-06 01:01:01' ） 、s(秒数时间戳) 、ms （毫秒数时间戳）
                    
                    //下拉选项框额外选项
                    options : formFieldInfo.options ? formFieldInfo.options : [],//下拉选项值
                    multiple: formFieldInfo.multiple ? formFieldInfo.multiple : false,//下拉选项是否多选
                    
                    optionsRemoteUrl           : formFieldInfo.optionsRemoteUrl ? formFieldInfo.optionsRemoteUrl : '',//ajax获取选项的url地址
                    optionsRemoteUrlMethod     : formFieldInfo.optionsRemoteUrlMethod ? formFieldInfo.optionsRemoteUrlMethod : 'get',//ajax获取选项的url地址的请求方式，对应axios的方法
                    optionsRemoteUrlData       : formFieldInfo.optionsRemoteUrlData ? formFieldInfo.optionsRemoteUrlData : {},//ajax 请求附带参数
                    optionsRemoteUrlParams     : formFieldInfo.optionsRemoteUrlParams ? formFieldInfo.optionsRemoteUrlParams : {},//ajax 请求附带参数
                    optionsRemoteQueryParamName: formFieldInfo.optionsRemoteQueryParamName ? formFieldInfo.optionsRemoteQueryParamName : 'query',//ajax 请求时搜索内容参数名
                    optionsRemoteSuccessFn     : formFieldInfo.optionsRemoteSuccessFn ? formFieldInfo.optionsRemoteSuccessFn : () => {},//ajax 请求时搜索内容参数名
                    optionsRemoteErrorFn       : formFieldInfo.optionsRemoteSuccessFn ? formFieldInfo.optionsRemoteSuccessFn : () => {},//ajax 请求时搜索内容参数名
                    optionsRemoteFieldNameValue: formFieldInfo.optionsRemoteFieldNameValue ? formFieldInfo.optionsRemoteFieldNameValue : 'value',//ajax 请求中值对应的属性
                    optionsRemoteFieldNameLabel: formFieldInfo.optionsRemoteFieldNameLabel ? formFieldInfo.optionsRemoteFieldNameLabel : 'label',//ajax请求中label对应的属性
                    optionRemoteGetOnce        : formFieldInfo.optionRemoteGetOnce ? formFieldInfo.optionRemoteGetOnce : false,//是否只进行一次ajax请求获取下拉框选项
                    filterable                 : formFieldInfo.filterable ? formFieldInfo.filterable : false,//要远程这个必须设置
                    remote                     : formFieldInfo.remote ? formFieldInfo.remote : false,//要远程这个必须设置
                    loadingText                : formFieldInfo.loadingText ? formFieldInfo.loadingText : '加载中...',//加载中的提示
                    toInteger                  : formFieldInfo.toInteger ? formFieldInfo.toInteger : false,//加载中的提示
    
                    //下拉选项框额外选项 是否启用禁用选项功能
                    optionsRemoteFieldNameDisabled: formFieldInfo.optionsRemoteFieldNameDisabled ? formFieldInfo.optionsRemoteFieldNameDisabled : 'disabled',//ajax请求中disabled对应的属性
                    optionsRemoteDisableSwitch    : formFieldInfo.optionsRemoteDisableSwitch ? formFieldInfo.optionsRemoteDisableSwitch : false,//ajax请求中disabled对应的属性
    
                    loading: false,
                    
                    //数字型额外选项
                    min      : formFieldInfo.min !== undefined ? formFieldInfo.min : -1e15,//数字型最小值
                    max      : formFieldInfo.max ? formFieldInfo.max : 1e15,//数字型最大值
                    precision: formFieldInfo.precision ? formFieldInfo.precision : 0,//数字型范围的精度，当为0时表示整数
                    step     : formFieldInfo.step ? formFieldInfo.step : 1,//点击增减数字值
                };
                
                //字段默认值设置
                if (formFieldInfo.fieldType === this.fieldTypeList.number) {
                    //数字表单字段额外处理
                    randomFormData[randomFiledName] = {min: null, max: null};
                    this.formNumberFieldList.push(randomFiledName);
                } else if (formFieldInfo.fieldType === this.fieldTypeList.datetimerange) {
                    //日期范围选项特殊处理
                    randomFormData[randomFiledName] = ['', '']
                } else {
                    randomFormData[randomFiledName] = '';
                }
            }
    
    
            //通过ajax一次获取下拉框选项
            if(existGetOnceOption){
                for(let indexFff in formFieldDefinedInfo){
                    let fieldDefinedInfo = formFieldDefinedInfo[indexFff];
                    if( fieldDefinedInfo.fieldType === this.fieldTypeList.select && fieldDefinedInfo.optionRemoteGetOnce){
                        let requestMethod = fieldDefinedInfo.optionsRemoteUrlMethod.toLocaleLowerCase(),
                            queryDataInfo = {
                            };
                        //ajax获取搜索记录
                        let axiosConfig = {
                            method: fieldDefinedInfo.optionsRemoteUrlMethod,
                            url   : fieldDefinedInfo.optionsRemoteUrl,
                            params: requestMethod === 'get' ? Object.assign({}, queryDataInfo, fieldDefinedInfo.optionsRemoteUrlParams) : fieldDefinedInfo.optionsRemoteUrlParams,
                            data  : Object.assign({}, queryDataInfo, fieldDefinedInfo.optionsRemoteUrlData),
                        };
                        axios.request(axiosConfig).then(res => {
                            if (res.data.code !== 0) {
                                this.$Message.error(res.data.msg);
                        
                                throw new Error(res.data.msg);
                            } else {
                                return res.data.data;
                            }
                        }).then(data => {
                            //获取列表数据
                            formFieldDefinedInfo[indexFff].options = data.map(item => {
                                return {
                                    value: item[formFieldDefinedInfo[indexFff].optionsRemoteFieldNameValue],
                                    label: item[formFieldDefinedInfo[indexFff].optionsRemoteFieldNameLabel],
                                    disabled: formFieldDefinedInfo[indexFff].optionsRemoteDisableSwitch ? (item[formFieldDefinedInfo[indexFff].optionsRemoteFieldNameDisabled] ? true : false) : false,
                                };
                            });
                            this.formFieldDefinedInfo = Object.assign({}, formFieldDefinedInfo);
                            this.formData             = Object.assign({}, randomFormData);
                        }).catch(err => {
                            console.log(err);
                        });
                    }
                }
            }else{
                this.formFieldDefinedInfo = Object.assign({}, formFieldDefinedInfo);
                this.formData             = Object.assign({}, randomFormData);
            }
        },
    }
</script>

<style scoped>
    .ivu-form-item {
        margin-bottom: 5px;
    }
</style>
